const global = getApp().globalData;
const util = global.util;
const Api = global.Api;
const wxApi = global.wxApi;
const store = global.store;
Page({
  data: {
    cards: [],
    level: null,
    mode: null,
    turnoff: false,
    timeText: '',
    playboardBg: 1,
    imgNums: [],
    countDownEnd: false,
    curImgNum: 1,
    promptShow: false,
    promptTitle: '恭喜打破自己最佳成绩！',
    promptMark: 1,
    promptText: '',
    promptBest: '',
    myBest: '',
    worldBest: '',
    showTurnoffBtn: false,
    viewShow: false,
    keepActive: true,
    activeNum: null,
    openNum: null,
    voiceType: 'open',
    pageShow: false
  },
  onLoad( options ) {
    let self = this;
    let params = util.decodeURI( options.params );
    let level = this.level = params.level;
    let mode =  this.mode = params.mode;
    this.setData({
      level: this.level,
      mode: this.mode
    });
    let navTitle = mode.name + '('+ level.size +'x'+ level.size +')'
    wxApi.setNavTitle( navTitle )
    this.setMyGrade( this.level.myBest, this.level.best );
    this.getImgNums();
    // this.audioContext = wxApi.initAudioContext( { src: '' } )
    this.timeoutImp(() => {
      self.setData({
        viewShow: true
      });
    }, 200);
  },
  onShow() {
    this.init();
  },
  onHide() {
    console.log( 'on hide' )
    this.clearTimer();
    this.countDownAudio && this.countDownAudio.stop();
  },
  onUnload() {
    this.countDownAudio && this.countDownAudio.stop();
    this.clearTimer();
  },
  init( fn ) {
    let self = this;
    this.msec = 0;
    this.curnum = 0;
    this.curActiveKey = ''; // 保存当前激活的key
    this.isTurnoffMode = this.mode.id >= 3; // 是否是闭眼模式
    this.setTurnoff( false ); // 闭眼模式下，是否开启闭眼
    // 点击错误时的节流函数
    this.tapErrorCard = util.throttle(this.tapErrorCard, 100);
    // 隐藏闭眼footer
    this.setData({
      showTurnoffBtn: false,
      timeText: '',
      promptShow: false,
      pageShow: false
    })
    
    this.getPlayVoice();
    this.timeoutImp(() => {
      
      this.initialCards( this.level.size );
      self.startCountDown();
      self.setData({
        pageShow: true
      })
    }, 200)
  },
  setPlayVoice( data ) {
    store.setPlayVoice( data );
    this.setVoiceType( data );
  },
  getPlayVoice() {
    store.getPlayVoice(( data ) => {
      data = data === "close" ? "close" : "open"
      this.setVoiceType( data );
    })
  },
  /**
   * 开始倒计时
   */
  startCountDown() {
    this.playAudio( 1 );
    
    this.countDown(() => {
      this.startTimerInterval();
      // 闭眼模式下，计时器结束，显示闭眼footer
      if ( this.isTurnoffMode ) {
        this.setData({
          showTurnoffBtn: true
        })
      }
    });
  },
  /**
   * 点击卡片
   */
  onTapCard( e ) {
    let dataset = e.currentTarget.dataset;
    let card = dataset.card;
    let index = dataset.index;
    let cardIsRight = this.cardIsRight( card.num );
    // 保证点击后时间正常
    let date = new Date();
    this.msec = date - this.startDate;
    this.setTimeformat( this.msec );
    if ( !cardIsRight ) {
      this.tapErrorCard( index );
    } else {
      this.tapRightCard( index, card );
    }
    
  },
  tapRightCard( index, card ) {
    console.log( 'tap card is right.' )
    let size = this.level.size;
    let mode = Number( this.mode.id );
    switch( mode ) {
      case 1: {
        console.log( '简单模式' );
        this.tapSimpleCard( index, card );
      } break;
      case 2: {
        console.log( '经典模式' );
        this.tapClassicCard( index, card );
      } break;
      case 3: {
        console.log( '闭眼模式' );
        if ( !this.getTurnoff() ) return;
        this.tapTurnoffCard( index, card );
      } break;
      case 4: {
        console.log( '闭眼PLUS' )
        if ( !this.getTurnoff() ) return;
        this.tapTurnoffPlusCard( index, card );
      } break;
    }
    this.playAudio( 2 );
    if ( size * size == card.num ) {
      // 完成游戏
      console.log( 'finish game.' );
      this.finishTraning()
    }
    this.curnum = card.num;
  },
  /**
   * 点击错误卡片
   */
  tapErrorCard( index ) {

    if ( this.mode.id <= 2 ) {
      this.setPlayboardBg( 2 );
    } else {
      if ( !this.getTurnoff() ) return;
      this.errorCurCard( index );
    }
    this.playAudio( 3 );
  },
  tapSimpleCard( index, card ) {
    this.activeCurCard( index );
  },
  tapClassicCard( index ) {
    this.activeCurCloseOther( index );
  },
  tapTurnoffCard( index ) {
    this.activeCurCard( index );
  },
  tapTurnoffPlusCard( index ) { 
    this.activeCurCloseOther( index );
  },
  /**
   * 开启闭眼
   *
   */
  onTurnoff() {
    this.setData({
      showTurnoffBtn: false
    })
    this.closeAllCards();
    this.setTurnoff( true );
  },
  /**
   * 声音开启或关闭
   */
  onVoiceOption() {
    let voiceType = this.getVoiceType();
    voiceType = voiceType === 'close' ? 'open' : 'close';
    this.setPlayVoice( voiceType );
  },
  /**
   * 完成练习
   */
  finishTraning() {
    let self = this;
    this.stopTimer();
    if ( this.msec == 0 ) {
      console.log( '系统异常' );
      return ;
    }
    let date = new Date();
    let msec = date - this.startDate;
    this.setTimeformat( msec );
    let params = {
      millis: msec,
      mode: this.mode.id,
      size: this.level.size
    }
    let myGradeParams = {
      mode: this.mode.id,
      size: this.level.size
    }
    Api.postTrainResult( params, result => {
      
      this.analyzeResult( result );
      Api.getMyGrade( myGradeParams, myGrade => {
        self.setLevel( myGrade );
      } )
    } )
    
  },
  cardIsRight( num ) {
    return num - this.curnum === 1;
  },
  /**
   * 开始计时
   */
  startTimerInterval() {
    let self = this;
    self.msec = 0;
    this.startDate = new Date();
    this.timerInterval = setInterval(() => {
      self.msec = self.msec + 80;
      self.setTimeformat( self.msec );
    }, 80); 
  },
  setTimeformat( msec ) {
    let t = util.msecFormat( msec );
    this.setData({
      timeText: t.minute + ':' + t.second + '.' + t.ms
    })
  },
  playAudio( type ) {
    if ( this.getVoiceType() === 'close' ) {
      return;
    }
    wx.stopBackgroundAudio();
    switch( type ) {
      // 倒计时
      case 1: {
        let countDownSrc = '/audios/concentration_321go.mp3';
        this.countDownAudioPlay( countDownSrc );
      } break;
      case 2: {
        let rightSrc = '/audios/concentration_right.wav';
        this.audioContextPlay( 'right', rightSrc );
      } break;
      case 3: {
        let wrongSrc = '/audios/duangduang.mp3'
        this.audioContextPlay( 'wrong', wrongSrc );
      } break;
    }
  },
  countDownAudioPlay( src ) {
    src = src || '/audios/concentration_321go.mp3';
    if( this.countDownAudio ) {
      this.countDownAudio.seek(0);
      this.countDownAudio.play();
    } else {
      this.countDownAudio = wxApi.initAudioContext( { src: src } )
      this.countDownAudio.play();
    }
  },
  tapRightAudioPlay( src ) {

  },
  audioContextPlay(type, src) {
    console.log( src );
    let audioContextsKey = type + 'AudioContexts';
    let curAudioContextKey = type + 'CurAudioContext';
    let curIndexKey = type + 'CurIndex';
    let audioCountKey = type + 'AudioCount';

    let audioContexts = this[audioContextsKey];
    let curAudioContext = this[curAudioContextKey];
    let audioCount = this[audioCountKey];
    let curIndex = this[curIndexKey];
    if ( audioContexts && curAudioContext ) {
      let lastAudioContext = audioContexts[ audioCount - curIndex - 1 ];
      lastAudioContext.stop();
      lastAudioContext.seek( 0 );
      curIndex ++;
      if ( curIndex >= audioCount ) {
        curIndex = 0;
      }
      console.log( curIndex );
      let nowAudioContext = audioContexts[ curIndex ];
      nowAudioContext.play();
      this[curIndexKey] = curIndex;
      return;
    }

    this[audioContextsKey] = [];
    this[curIndexKey] = 0;
    this[audioCountKey] = 4;
    this[curAudioContextKey] = null;
    curAudioContext = this[curAudioContextKey];
    for ( let i = 0; i < this[audioCountKey]; i ++) {
      let audioContext = wxApi.initAudioContext( { src: src } )
      this[audioContextsKey].push( audioContext );
    }
    curAudioContext = this[audioContextsKey][ 0 ];
    curAudioContext.src = src;
    curAudioContext.play();
    this[curAudioContextKey] = curAudioContext;
  },
  /**
   * 停止计时
   */
  stopTimer() {
    clearInterval( this.timerInterval );
    this.timerInterval = null;
  },
  /**
   * 退出
   */
  onPromptOut() {
    this.closePrompt();
    wx.navigateBack();
  },
  /**
   * 重新开始
   */
  onPromptRestart() {
    this.closePrompt();
    this.setTimeText('');
    this.init();
  },
  /**
   * 显示所有卡片
   */
  openAllCards() {
    let cards = this.setCardsAttr( 'close', false );
    this.setCards( cards );
  },
  /**
   * 隐藏所有卡片
   */
  closeAllCards() {
    let cards = this.setCardsAttr( 'close', true );
    this.setCards( cards );
  },
  /**
   * 激活当前卡片
   */
  activeCurCard( index ) {
    let key = 'cards[' + index + ']' + '.active';
    this.curActiveKey = key;
    let obj = {};
    obj[ key ] = true;
    this.setData( obj );
  },
  /**
   * 激活当前卡片，关闭其他卡片
   */
  activeCurCloseOther( index ) {
    let obj = {};
    let key = 'cards[' + index + ']' + '.active';
    obj[ key ] = true;
    if ( this.curActiveKey ) {
      obj[ this.curActiveKey ] = false;
    }
    this.curActiveKey = key;
    this.setData( obj );
  },
  /**
   * 卡片点选错误
   */
  errorCurCard( index ) {
    let self = this;
    let obj = {};
    let key = 'cards[' + index + ']' + '.error';
    obj[ key ] = true;
    obj.playboardBg = 2;
    this.setData( obj );
    this.timeoutImp( () => {
      obj[ key ] = false;
      obj.playboardBg = 1;
      self.setData( obj );
    }, 200)
  },
  /**
   * 卡片数据模型
   */
  cardModal( num ) {
    return {
      num: num,
      active: false,
      close: false,
      error: false
    }
  },
  /**
   * 设置是否开启闭眼
   */
  setTurnoff( val ) {
    if ( val ) {
      // 遮盖所有卡片
      this.closeAllCards();
    } else {
      // 显示所有卡片
      this.openAllCards();
    }
    this.setData({
      turnoff: val
    })
  },
  /**
   * 是否开启闭眼
   */
  getTurnoff() {
    return this.data.turnoff;
  },
  setTimeText( text ) {
    this.setData({
      timeText: text
    })
  },
  getTimeText() {
    return this.data.timeText
  },
  setVoiceType( val ) {
    this.setData({
      voiceType: val
    })
  },
  getVoiceType() {
    return this.data.voiceType
  },
  /**
   * 设置面板颜色
   * 0: 绿色 1: 灰色 2: 红色
   */
  setPlayboardBg( type ) {
    let self = this;
    this.setData({
      playboardBg: type
    });
    if ( type == 2) {
      this.timeoutImp(() => {
        self.setData({
          playboardBg: 1
        })
      }, 200)
    }
  },
  /**
   * 设置卡片显示属性
   */
  setCardsAttr( attr, value ) {
    let cards = this.getCards();
    for( let i = 0, len = cards.length; i < len; i ++ ) {
      cards[ i ][ attr ] = value;
    }
    return cards;
  },
  getCards() {
   return this.data.cards;
  },
  setCards( cards ) {
    this.setData({
      cards: cards
    })
  },
  setMyGrade( mbest, wbest ) {
    let mtime = util.msecFormat( mbest );
    let wtime = util.msecFormat( wbest );
    mbest = this.timeFormat( mtime );
    wbest = this.timeFormat( wtime );
    this.setData({
      myBest: mbest,
      worldBest: wbest
    })
  },
  setLevel( myGrade ) {
    this.setMyGrade( myGrade.myBest, myGrade.best );
    this.setData({
      level: myGrade
    })
  },
  getBestText( best ) {
    let time = util.msecFormat( best );
    return '我的最佳：' + this.timeFormat( time );
  },
  setWorldBest( msec ) {
    let time = util.msecFormat( msec );
    let best = this.timeFormat( time );
    this.setData({
      worldBest: best
    })
  },
  /**
   * 首次完成训练弹窗
   */
  showFirstFinishPrompt( rank ) {
    let size = this.level.size;
    let modeName = this.mode.name;

    rank = Number( rank );
    let title = '恭喜首次完成 '+ modeName +' 模式（'+ size +'x'+ size +'）'
    title = rank <= 100 ? title + '全网排名：第'+ rank +'名！' : title;

    let text = '当前用时：' + this.data.timeText;

    this.showFinishPrompt({
      title: title,
      mark: 1,
      text: text
    })
  },
  /**
   * 突破最佳成绩弹窗
   */
  showBreakSelfPrompt( rank, best ) {
    let text = '当前用时：' + this.data.timeText;
    let title = '恭喜打破自己最佳成绩！';
    title = rank <= 100 ? title + '全网排名：第'+ rank +'名！' : title; 
    best = this.getBestText( best );
    this.showFinishPrompt({
      title: title,
      text: text,
      mark: 2,
      best: best
    })
  },
  /**
   * 未突破最佳成绩弹窗
   */
  showNoBreakPrompt( best ) {
    let title = '未能打破自己的最佳成绩～再接再厉！';
    let text = '当前用时：' + this.data.timeText;
    best = this.getBestText( best );
    this.showFinishPrompt({
      title: title,
      text: text,
      mark: 0,
      best: best
    })
  },
  showFinishPrompt( param ) {
    this.setData({
      promptShow: true,
      promptTitle: param.title,
      promptMark: param.mark || 0,
      promptText: param.text || '',
      promptBest: param.best || ''
    })
  },
  
  analyzeResult( params ) {
    if ( !params ) {
      wx.showToast({
        title: '系统异常',
        icon: 'none'
      })
      return;
    }
    let broken = params.broken;
    let myBest = params.myBest;
    let rank = params.rank;
    let current = params.current;
    // 是否突破最佳成绩
    if ( broken ) {
      // 突破成绩
      this.showBreakSelfPrompt( rank, myBest );
    } else {
      if ( myBest ) {
        // 未突破
        this.showNoBreakPrompt( myBest );
      } else {
        // 首次完成
        this.showFirstFinishPrompt( rank );
      }
    }
  },
  closePrompt() {
    this.setData({
      promptShow: false
    })
  },
  timeFormat( time ) {
    return time.minute + ':' + time.second + '.' + time.ms;
  },
  clearTimer() {
    clearInterval( this.timerInterval );
    clearInterval( this.countDownInterval );
    this.countDownInterval = null;
    this.timerInterval = null;
  },
  showCards() {
    this.setData({
      cardsShow: true
    })
  },
  hideCards() {
    this.setData({
      cardsShow: false
    })
  },
  /**
   * 初始化卡片数组
   */
  initialCards( size ) {
    let cards = [];
    let nums = util.orderNums( size * size, 1 );
    nums = util.shuffle( nums );
    for ( let i = 0, len = nums.length; i < len; i ++ ) {
      let card = this.cardModal( nums[i] );
      cards.push( card );
    }
    this.setCards( cards );
    return cards;
  },
  /**
   * 倒计时图片数组初始化
   *
   * @returns
   */
  getImgNums() {
    let arr = [];
    for( let i = 1; i <= 26; i++ ) {
      arr.push( i );
    }
    this.setData({
      imgNums: arr
    })
    return arr;
  },
  /**
   * 计时器
   *
   * @param {*} fn
   */
  countDown(fn) {
    let self = this;
    let curImgNum = 1;
    self.setData({
      countDownEnd: false,
      curImgNum: 1
    })
    this.countDownInterval = setInterval(() => {
      curImgNum ++;
      self.setData({
        curImgNum: curImgNum
      })
      if ( curImgNum >= 26 ) {
        clearInterval( self.countDownInterval );
        self.countDownInterval = null;
        self.setData({
          countDownEnd: true
        })
        fn();
      }
    }, 115);
  },
  timeoutImp( fn, time ) {
    let timeout = setTimeout(() => {
      fn && fn()
      clearTimeout( timeout );
      timeout = null;
    }, time);
  },
  nowDate() {
    return new Date();
  }
});
